Passed
Push — main ( 6facca...56d5bd )
by Andrii
02:21
created

ts.test.ts ➔ thising   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
1
import { ClassHash as V, CssModule } from "../src/types"
2
3
const {keys: $keys} = Object
4
5
it("`in string` vs `:string`", () => {
6
  type In = {[k in string]: boolean}
7
  type Colon = {[k: string]: boolean}
8
  
9
  function check1(_: {some: boolean}) {}
10
  function checkR<K extends string>(_: {[k in K]: boolean}) {}
11
  function checkC(_: {[k: string]: boolean}) {}
12
13
  const input1: In = {}, input2: Colon = {}
14
  //@ts-expect-error
15
  check1(input1)
16
  //@ts-expect-error
17
  check1(input2)
18
  checkR(input1)
19
  checkR(input2)
20
  checkC(input1)
21
  checkC(input2)
22
23
}) 
24
25
describe("this", () => {
26
  type Context = {context: string}
27
  
28
  it.todo("`this?` is illegal")
29
30
  it("|void - NOPE", () => {  
31
    function thising(this: void | Context): typeof this extends Context ? true : null {
32
      //@ts-expect-error
33
      return this && 'context' in this
34
      ? true
35
      : null
36
    }
37
  
38
    const suite1 = thising()
39
    , suite2 = thising.bind({context: ""})()
40
    , suite1Check: Record<string, typeof suite1> = {
41
      "null": null,
42
      //@ts-expect-error
43
      "true": true
44
    }
45
    , suite2Check: Record<string, typeof suite2> = {
46
      //TODO #13 @ts-expect-error
47
      "null": null,
48
      //@ts-expect-error //TODO #13
49
      "true": true
50
    }
51
52
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
53
  })
54
55
  it("|undefined - NOPE", () => {  
56
    function thising(this: undefined | Context): typeof this extends Context ? true : null {
57
      //@ts-expect-error
58
      return this && 'context' in this
59
      ? true
60
      : null
61
    }
62
  
63
    //@ts-expect-error //TODO #13 The 'this' context of type 'void' is not assignable
64
    const suite1 = thising()
65
    , suite2 = thising.bind({context: ""})()
66
    , suite1Check: Record<string, typeof suite1> = {
67
      "null": null,
68
      //@ts-expect-error
69
      "true": true
70
    }
71
    , suite2Check: Record<string, typeof suite2> = {
72
      //TODO #13 @ts-expect-error
73
      "null": null,
74
      //@ts-expect-error //TODO #13
75
      "true": true
76
    }
77
78
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
79
  })
80
81
  it("|unknown - NOPE", () => {  
82
    function thising(this: unknown | Context): typeof this extends Context ? true : null {
83
      //@ts-expect-error
84
      return this && 'context' in this
85
      ? true
86
      : null
87
    }
88
  
89
    const suite1 = thising()
90
    , suite2 = thising.bind({context: ""})()
91
    , suite1Check: Record<string, typeof suite1> = {
92
      "null": null,
93
      //@ts-expect-error
94
      "true": true
95
    }
96
    , suite2Check: Record<string, typeof suite2> = {
97
      //TODO #13 @ts-expect-error
98
      "null": null,
99
      //@ts-expect-error //TODO #13
100
      "true": true
101
    }
102
103
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
104
  })
105
106
  it("overload", () => {
107
    function thising(): null
108
    function thising(this: Context): true 
109
    function thising(this: void | Context) {
110
      return this && 'context' in this
111
      ? true
112
      : null
113
    }
114
  
115
    const suite1 = thising()
116
    , suite2 = thising.bind({context: ""})()
117
    , suite1Check: Record<string, typeof suite1> = {
118
      "null": null,
119
      //@ts-expect-error
120
      "true": true
121
    }
122
    , suite2Check: Record<string, typeof suite2> = {
123
      //@ts-expect-error
124
      "null": null,
125
      "true": true
126
    }
127
128
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
129
  })
130
131
  it("throw variable - Nope", () => {
132
    function _thising(this: void | Context) {
133
      return this && 'context' in this
134
      ? true
135
      : null
136
    }
137
138
    //Same for ((this: Context) => true) | () => null)
139
    type Thising = (<T>(this: T) => T extends Context ? true : null)
140
141
    const thising = _thising as Thising
142
143
    const suite1 = thising()
144
    , binded = thising.bind({context: ""})
145
    , suite2 = binded()
146
    , suite1Check: Record<string, typeof suite1> = {
147
      "null": null,
148
      //@ts-expect-error
149
      "true": true
150
    }
151
    , suite2Check: Record<string, typeof suite2> = {
152
      //TODO #13 @ts-expect-error
153
      "null": null,
154
      //@ts-expect-error //TODO #13
155
      "true": true
156
    }
157
158
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
159
  })
160
161
  it("idfn this", () => {
162
    function thising<T>(this: T) {
163
      return this
164
    }
165
166
    const suite = thising()
167
    , suiteCheck: Record<string, typeof suite> = {
168
      "void": undefined
169
    }
170
    
171
    expect({suiteCheck}).toBeInstanceOf(Object)
172
  })
173
})
174
175
describe("UX of TS choice", () => {
176
  type T1 = {
177
    class1: string,
178
    class2: undefined
179
  }
180
181
  // it("union", () => {
182
  //   type tUnion<S extends CssModule> = (
183
  //     <A extends {[K in keyof S]?: V}>(source: A) => string
184
  //   ) | (
185
  //     <A extends {[K in keyof S]?: V}>(inject: string, source: A) => string
186
  //   );
187
    
188
  //   // const str = <S extends CssModule>(arg1: strS) => $keys(source).join(" ")
189
  // })
190
191
  // it("expression 1", () => {
192
  //   type tExpression1<S extends CssModule> = (
193
  //     <A extends {[K in keyof S]?: V}>(arg0: string|A, arg1?: typeof arg0 extends string ? A : never) => string
194
  //   );  
195
  // })
196
197
  // it("overload interface", () => {
198
  //   interface iOverload<S extends CssModule> {
199
  //     <A extends {[K in keyof S]?: V}>(arg0: string): string
200
  //     <A extends {[K in keyof S]?: V}>(arg0: string, arg1: A): string
201
  //   }  
202
  // })
203
204
  it("overload function", () => {
205
    function joiner<S extends CssModule>(source: {[K in keyof S]?: V}) :string
206
    function joiner<S extends CssModule>(inj: string, source: {[K in keyof S]?: V}) :string
207
    function joiner<S extends CssModule, F1 extends {[K in keyof S]?: V} | string>(
208
      arg0: F1,
209
      // arg1?: typeof arg0 extends string ? {[K in keyof S]?: V} : never 
210
      arg1?: F1 extends string ? Exclude<F1, string> : never
211
    ) {
212
      return `${
213
        typeof arg0 === "string" ? arg0 : $keys(arg0) 
214
      } ${
215
        arg1 === undefined ? "" : $keys(arg1).join(" ")
216
      }`.trim()
217
    }
218
219
    const bothObjects = joiner<T1>(
220
      //@ts-expect-error Argument of type '{ class1: string; }' is not assignable to parameter of type 'string'
221
      {class1: ""},
222
      {class2: ""}
223
    )
224
    , redundantKey = joiner<T1>(
225
      //@ts-expect-error Argument of type '{ class3: string; }' is not assignable
226
      {class3: ""}
227
    )
228
    
229
    expect({bothObjects, redundantKey}).toBeInstanceOf(Object)
230
  })
231
})
232